package com.bookrecomm.crawler.service.impl;

import com.bookrecomm.crawler.entity.Book;
import com.bookrecomm.crawler.entity.Category;
import com.bookrecomm.crawler.entity.Comment;
import com.bookrecomm.crawler.entity.Tag;
import com.bookrecomm.crawler.service.AbstractBookCrawler;
import com.bookrecomm.crawler.util.HttpUtil;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import io.github.bonigarcia.wdm.WebDriverManager;

import java.math.BigDecimal;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 亚马逊图书爬虫实现类
 * 使用Selenium处理动态加载内容和反爬虫机制
 */
@Slf4j
public class AmazonCrawler extends AbstractBookCrawler {

    // 亚马逊图书列表页URL模板
    private static final String LIST_URL_TEMPLATE = "https://www.amazon.cn/s?i=stripbooks&rh=n%%3A%s&page=%d";
    
    // WebDriver实例
    private WebDriver driver;
    
    /**
     * 构造函数，初始化WebDriver
     */
    public AmazonCrawler() {
        initWebDriver();
    }
    
    /**
     * 初始化WebDriver
     */
    private void initWebDriver() {
        try {
            // 自动下载和配置WebDriver
            WebDriverManager.chromedriver().setup();
            
            // 配置Chrome选项
            ChromeOptions options = new ChromeOptions();
            options.addArguments("--headless"); // 无头模式
            options.addArguments("--disable-gpu");
            options.addArguments("--window-size=1920,1080");
            options.addArguments("--disable-extensions");
            options.addArguments("--no-sandbox");
            options.addArguments("--disable-dev-shm-usage");
            options.addArguments("--user-agent=" + HttpUtil.getRandomUserAgent());
            
            // 创建Chrome驱动
            driver = new ChromeDriver(options);
            log.info("WebDriver初始化成功");
        } catch (Exception e) {
            log.error("WebDriver初始化失败", e);
        }
    }
    
    /**
     * 关闭WebDriver
     */
    public void closeWebDriver() {
        if (driver != null) {
            driver.quit();
            log.info("WebDriver已关闭");
        }
    }
    
    @Override
    public List<String> crawlBookListPage(String categoryId, int pageNum) {
        List<String> detailUrls = new ArrayList<>();
        
        // 构造分页URL
        String pageUrl = String.format(LIST_URL_TEMPLATE, categoryId, pageNum);
        log.info("爬取亚马逊图书列表页: {}", pageUrl);
        
        try {
            // 使用WebDriver加载页面
            driver.get(pageUrl);
            
            // 等待页面加载完成
            WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
            wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("div.s-result-item")));
            
            // 获取图书列表
            List<WebElement> bookItems = driver.findElements(By.cssSelector("div.s-result-item[data-component-type='s-search-result']"));
            
            for (WebElement item : bookItems) {
                try {
                    WebElement linkElement = item.findElement(By.cssSelector("h2 a"));
                    String detailUrl = linkElement.getAttribute("href");
                    
                    if (detailUrl != null && !detailUrl.isEmpty()) {
                        detailUrls.add(detailUrl);
                        log.debug("找到亚马逊图书详情页: {}", detailUrl);
                    }
                } catch (Exception e) {
                    log.debug("解析图书项失败", e);
                }
            }
            
            log.info("亚马逊列表页 {} 共找到 {} 本图书", pageUrl, detailUrls.size());
            
            // 随机等待，避免频繁请求
            HttpUtil.randomSleep(2, 5);
            
        } catch (Exception e) {
            log.error("爬取亚马逊图书列表页失败: {}", pageUrl, e);
        }
        
        return detailUrls;
    }

    @Override
    public Book crawlBookDetailPage(String url) {
        log.info("爬取亚马逊图书详情页: {}", url);
        
        Book book = new Book();
        
        try {
            // 使用WebDriver加载页面
            driver.get(url);
            
            // 等待页面加载完成
            WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
            wait.until(ExpectedConditions.presenceOfElementLocated(By.id("productTitle")));
            
            // 提取标题
            WebElement titleElement = driver.findElement(By.id("productTitle"));
            book.setTitle(titleElement.getText().trim());
            
            // 提取作者
            try {
                WebElement authorElement = driver.findElement(By.cssSelector("span.author a"));
                book.setAuthor(authorElement.getText().trim());
            } catch (Exception e) {
                log.debug("未找到作者信息", e);
            }
            
            // 提取价格
            try {
                WebElement priceElement = driver.findElement(By.cssSelector(".a-price .a-offscreen"));
                String priceText = priceElement.getText().replace("￥", "").trim();
                book.setPrice(new BigDecimal(priceText));
            } catch (Exception e) {
                log.debug("未找到价格信息", e);
                book.setPrice(new BigDecimal("0.00"));
            }
            
            // 提取封面图片URL
            try {
                WebElement imageElement = driver.findElement(By.id("imgBlkFront"));
                book.setCoverUrl(imageElement.getAttribute("src"));
            } catch (Exception e) {
                log.debug("未找到封面图片", e);
            }
            
            // 提取图书描述
            try {
                WebElement descElement = driver.findElement(By.id("bookDescription_feature_div"));
                book.setDescription(descElement.getText().trim());
            } catch (Exception e) {
                log.debug("未找到图书描述", e);
            }
            
            // 提取图书详情
            try {
                WebElement detailsElement = driver.findElement(By.id("detailBullets_feature_div"));
                String detailsText = detailsElement.getText();
                
                // 提取ISBN
                Pattern isbnPattern = Pattern.compile("ISBN-13:\\s*(\\d+-\\d+-\\d+-\\d+-\\d+)");
                Matcher isbnMatcher = isbnPattern.matcher(detailsText);
                if (isbnMatcher.find()) {
                    book.setIsbn(isbnMatcher.group(1));
                }
                
                // 提取出版社
                Pattern publisherPattern = Pattern.compile("出版社\\s*:\\s*([^;\\n]+)");
                Matcher publisherMatcher = publisherPattern.matcher(detailsText);
                if (publisherMatcher.find()) {
                    book.setPublisher(publisherMatcher.group(1).trim());
                }
                
                // 提取页数
                Pattern pagesPattern = Pattern.compile("页数\\s*:\\s*(\\d+)");
                Matcher pagesMatcher = pagesPattern.matcher(detailsText);
                if (pagesMatcher.find()) {
                    book.setPages(Integer.parseInt(pagesMatcher.group(1)));
                }
                
                // 提取语言
                Pattern languagePattern = Pattern.compile("语种\\s*:\\s*([^;\\n]+)");
                Matcher languageMatcher = languagePattern.matcher(detailsText);
                if (languageMatcher.find()) {
                    book.setLanguage(languageMatcher.group(1).trim());
                } else {
                    book.setLanguage("中文");
                }
            } catch (Exception e) {
                log.debug("提取图书详情失败", e);
            }
            
            // 提取分类信息
            List<Category> categories = new ArrayList<>();
            try {
                WebElement breadcrumbElement = driver.findElement(By.id("wayfinding-breadcrumbs_feature_div"));
                List<WebElement> categoryElements = breadcrumbElement.findElements(By.cssSelector("a"));
                
                int level = 1;
                for (WebElement element : categoryElements) {
                    String categoryName = element.getText().trim();
                    if (!categoryName.isEmpty()) {
                        Category category = new Category();
                        category.setName(categoryName);
                        category.setLevel(level++);
                        categories.add(category);
                    }
                }
            } catch (Exception e) {
                log.debug("提取分类信息失败", e);
            }
            book.setCategories(categories);
            
            // 提取标签信息
            List<Tag> tags = new ArrayList<>();
            try {
                // 点击"查看更多"按钮展开全部标签
                try {
                    WebElement moreButton = driver.findElement(By.cssSelector("#tmmSwatches .a-link-normal"));
                    moreButton.click();
                    Thread.sleep(1000);
                } catch (Exception e) {
                    // 忽略错误，可能没有"查看更多"按钮
                }
                
                List<WebElement> tagElements = driver.findElements(By.cssSelector(".zg_hrsr_item"));
                for (WebElement element : tagElements) {
                    String tagText = element.getText().trim();
                    if (!tagText.isEmpty()) {
                        Tag tag = new Tag();
                        tag.setName(tagText);
                        tag.setHeat(1); // 默认热度
                        tags.add(tag);
                    }
                }
            } catch (Exception e) {
                log.debug("提取标签信息失败", e);
            }
            book.setTags(tags);
            
            // 提取评分
            try {
                WebElement ratingElement = driver.findElement(By.id("acrPopover"));
                String ratingText = ratingElement.getAttribute("title");
                Pattern ratingPattern = Pattern.compile("(\\d+\\.\\d+)");
                Matcher ratingMatcher = ratingPattern.matcher(ratingText);
                if (ratingMatcher.find()) {
                    book.setRating(new BigDecimal(ratingMatcher.group(1)));
                } else {
                    book.setRating(new BigDecimal("0.0"));
                }
            } catch (Exception e) {
                log.debug("提取评分失败", e);
                book.setRating(new BigDecimal("0.0"));
            }
            
            // 提取评分人数
            try {
                WebElement ratingCountElement = driver.findElement(By.id("acrCustomerReviewText"));
                String countText = ratingCountElement.getText();
                Pattern countPattern = Pattern.compile("(\\d+)");
                Matcher countMatcher = countPattern.matcher(countText);
                if (countMatcher.find()) {
                    book.setRatingCount(Integer.parseInt(countMatcher.group(1)));
                } else {
                    book.setRatingCount(0);
                }
            } catch (Exception e) {
                log.debug("提取评分人数失败", e);
                book.setRatingCount(0);
            }
            
            // 设置默认值
            book.setStatus(1);
            book.setCreatedAt(new Date());
            book.setUpdatedAt(new Date());
            
            // 提取评论
            List<Comment> comments = new ArrayList<>();
            try {
                // 点击评论标签页
                try {
                    WebElement reviewsTab = driver.findElement(By.cssSelector("#customerReviews"));
                    reviewsTab.click();
                    Thread.sleep(2000);
                } catch (Exception e) {
                    // 忽略错误，可能已经在评论页面
                }
                
                List<WebElement> commentElements = driver.findElements(By.cssSelector(".review"));
                for (WebElement element : commentElements) {
                    Comment comment = new Comment();
                    
                    // 提取评论内容
                    try {
                        WebElement contentElement = element.findElement(By.cssSelector(".review-text"));
                        comment.setContent(contentElement.getText().trim());
                    } catch (Exception e) {
                        continue; // 跳过没有内容的评论
                    }
                    
                    // 提取评分
                    try {
                        WebElement ratingElement = element.findElement(By.cssSelector(".review-rating"));
                        String ratingText = ratingElement.getText();
                        Pattern ratingPattern = Pattern.compile("(\\d+\\.\\d+)");
                        Matcher ratingMatcher = ratingPattern.matcher(ratingText);
                        if (ratingMatcher.find()) {
                            comment.setRating(new BigDecimal(ratingMatcher.group(1)));
                        } else {
                            comment.setRating(new BigDecimal("5.0"));
                        }
                    } catch (Exception e) {
                        comment.setRating(new BigDecimal("5.0"));
                    }
                    
                    // 提取点赞数
                    try {
                        WebElement likesElement = element.findElement(By.cssSelector(".cr-vote-text"));
                        String likesText = likesElement.getText();
                        Pattern likesPattern = Pattern.compile("(\\d+)");
                        Matcher likesMatcher = likesPattern.matcher(likesText);
                        if (likesMatcher.find()) {
                            comment.setLikes(Integer.parseInt(likesMatcher.group(1)));
                        } else {
                            comment.setLikes(0);
                        }
                    } catch (Exception e) {
                        comment.setLikes(0);
                    }
                    
                    comment.setStatus(1);
                    comments.add(comment);
                }
            } catch (Exception e) {
                log.debug("提取评论失败", e);
            }
            book.setComments(comments);
            
            log.info("爬取亚马逊图书详情成功: {}", book.getTitle());
        } catch (Exception e) {
            log.error("爬取亚马逊图书详情失败: {}", url, e);
        }
        
        // 随机等待，避免频繁请求
        HttpUtil.randomSleep(2, 5);
        
        return book;
    }

    @Override
    public List<String> crawlBookComments(String bookId, int pageNum) {
        // 亚马逊评论已在详情页中爬取，这里返回空列表
        return new ArrayList<>();
    }

    @Override
    public void startCrawl(String categoryId, int pageStart, int pageEnd) {
        log.info("开始爬取亚马逊分类 {} 的图书，页码范围: {} - {}", categoryId, pageStart, pageEnd);
        
        int successCount = 0;
        int failCount = 0;
        
        try {
            for (int page = pageStart; page <= pageEnd; page++) {
                // 爬取列表页
                List<String> detailUrls = crawlBookListPage(categoryId, page);
                
                // 爬取详情页
                for (String detailUrl : detailUrls) {
                    Book book = crawlBookDetailPage(detailUrl);
                    if (book != null) {
                        // 保存图书数据
                        boolean success = saveBook(book);
                        if (success) {
                            successCount++;
                            log.info("成功保存亚马逊图书: {}", book.getTitle());
                        } else {
                            failCount++;
                            log.error("保存亚马逊图书失败: {}", book.getTitle());
                        }
                    } else {
                        failCount++;
                    }
                }
                
                log.info("完成亚马逊第 {} 页爬取，成功: {}，失败: {}", page, successCount, failCount);
            }
        } finally {
            // 关闭WebDriver
            closeWebDriver();
        }
        
        log.info("亚马逊分类 {} 爬取完成，总成功: {}，总失败: {}", categoryId, successCount, failCount);
    }
}
